/*******************************************************************************
 *	:  IO
 *******************************************************************************/
#define PORT_PIN_CTEAT
#include "bsp.h"
#include "bsp_io.h"
#include "iohandle.h"
#include "pincfg.h"
#include "mytype.h"

/*******************************************************************************
 * @brief  IO VAL
 *******************************************************************************/
#define GPIO_INIT_HIGH 1
#define GPIO_INIT_LOW  0

/*******************************************************************************
 * @brief  fun
 *******************************************************************************/
void bsp_pin_mux_cfg(GPIO_T *port, uint32_t pin, uint8_t gpio_mux);

/*******************************************************************************
 * @brief  gpio cfg list
 *******************************************************************************/
static gpio_init_cfg_type gpio_cfg[] = {

	// LED
	{GPIOE, GPIO_MODE_OUT, GPIO_OTYPE_PP, GPIO_PUPD_NOPULL, GPIO_SPEED_25MHz, GPIO_INIT_HIGH, GPIO_PIN_5 | GPIO_PIN_6},
	
	// KEY
	{GPIOA, GPIO_MODE_IN, GPIO_OTYPE_PP, GPIO_PUPD_UP, GPIO_SPEED_25MHz, GPIO_INIT_HIGH, GPIO_PIN_0 | GPIO_PIN_1},

	// UART1-PA9:TX-PA10:RX
	{GPIOA, GPIO_MODE_AF, GPIO_OTYPE_PP, GPIO_PUPD_NOPULL, GPIO_SPEED_50MHz, GPIO_AF_USART1, GPIO_PIN_9 | GPIO_PIN_10},
	
	// UART2-PD5-TX:-PD6:RX
	{GPIOD, GPIO_MODE_AF, GPIO_OTYPE_PP, GPIO_PUPD_NOPULL, GPIO_SPEED_50MHz, GPIO_AF_USART2, GPIO_PIN_5 | GPIO_PIN_6},
	
	// UART3-PD8-TX:-PD9:RX
	{GPIOD, GPIO_MODE_AF, GPIO_OTYPE_PP, GPIO_PUPD_NOPULL, GPIO_SPEED_50MHz, GPIO_AF_USART3, GPIO_PIN_8 | GPIO_PIN_9},
	
	// UART4-PC10:TX-PC11:RX
	{GPIOC, GPIO_MODE_AF, GPIO_OTYPE_PP, GPIO_PUPD_NOPULL, GPIO_SPEED_50MHz, GPIO_AF_UART4, GPIO_PIN_10 | GPIO_PIN_11},
	
	// UART6-PC6-TX:-PC7:RX
	{GPIOC, GPIO_MODE_AF, GPIO_OTYPE_PP, GPIO_PUPD_NOPULL, GPIO_SPEED_50MHz, GPIO_AF_USART6, GPIO_PIN_6 | GPIO_PIN_7},
	
	// SPI1-PB3:SCK-PB4:MISO-PB5:MOSI
	{GPIOB, GPIO_MODE_AF, GPIO_OTYPE_PP, GPIO_PUPD_NOPULL, GPIO_SPEED_100MHz, GPIO_AF_SPI1, GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5},
	// SPI1 SS
	{GPIOB, GPIO_MODE_OUT, GPIO_OTYPE_PP, GPIO_PUPD_NOPULL, GPIO_SPEED_100MHz, GPIO_INIT_HIGH, GPIO_PIN_6 | GPIO_PIN_7 },
	
	// SW IIC PB8 PB9 
	{GPIOB, GPIO_MODE_IN, GPIO_OTYPE_PP, GPIO_PUPD_UP, GPIO_SPEED_25MHz, GPIO_INIT_HIGH, GPIO_PIN_8 | GPIO_PIN_9},
};

/*******************************************************************************
 * @brief  bsp_gpio_init
 * \param[in] us delay
 * \retval: none
 *******************************************************************************/
void bsp_gpio_init(void)
{
	int index;

	/* 开启时钟 */
	RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOA);
	RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOB);
	RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOC);
	RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOD);
	RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOE);
	RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOF);
	RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOG);
	RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOH);
	RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOI);
	RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOJ);
	RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOK);
	
	/* gpio cfg */
	for (index = 0; index < sizeof(gpio_cfg) / sizeof(gpio_init_cfg_type); index++)
	{
		GPIO_Config_T GPIO_InitStruct;

		GPIO_ConfigStructInit(&GPIO_InitStruct);

		GPIO_InitStruct.pin = gpio_cfg[index].pin;
		GPIO_InitStruct.mode = gpio_cfg[index].mode;
		GPIO_InitStruct.otype = gpio_cfg[index].otype;
		GPIO_InitStruct.pupd = gpio_cfg[index].pull;
		GPIO_InitStruct.speed = gpio_cfg[index].speed;

		GPIO_Config(gpio_cfg[index].port, &GPIO_InitStruct);

		/* 输出端口初始值 */
		if (gpio_cfg[index].mode == GPIO_MODE_OUT)
		{
			if (gpio_cfg[index].fun)
				GPIO_SetBit(gpio_cfg[index].port, gpio_cfg[index].pin);
			else
				GPIO_ResetBit(gpio_cfg[index].port, gpio_cfg[index].pin);
		}

		/* 外设复用功能 */
		if (gpio_cfg[index].mode == GPIO_MODE_AF)
		{
			bsp_pin_mux_cfg(gpio_cfg[index].port, gpio_cfg[index].pin, gpio_cfg[index].fun);
		}
	}
}

/*******************************************************************************
 * @brief  bsp_gpio
 * \param[in] us delay
 * \retval: none
 *******************************************************************************/
void bsp_pin_mux_cfg(GPIO_T *port, uint32_t pin, uint8_t gpio_mux)
{
	loop(16)
	{
		if ((1UL << index) & pin)
		{
			GPIO_ConfigPinAF(port, index, gpio_mux);
		}
	}
}

/*******************************************************************************
 * @brief  bsp_gpio
 * \param[in] us delay
 * \retval: none
 *******************************************************************************/
void bsp_gpio_mode_out_pp(GPIO_T *port, uint8_t pin)
{
	intx_alloc();

	intx_disable();

	group_bits2_set(port->MODE, pin, 1UL);
	group_bits1_set(port->OMODE, pin, 0UL);
	group_bits2_set(port->OSSEL, pin, 2UL);

	intx_enable();
}

void bsp_gpio_mode_out_od(GPIO_T *port, uint8_t pin)
{
	intx_alloc();

	intx_disable();

	group_bits2_set(port->MODE, pin, 1UL);
	group_bits1_set(port->OMODE, pin, 1UL);
	group_bits2_set(port->OSSEL, pin, 2UL);

	intx_enable();
}

void bsp_gpio_mode_out_pp_spd(GPIO_T *port, uint8_t pin, uint32_t spd)
{
	intx_alloc();

	intx_disable();

	group_bits2_set(port->MODE, pin, 1UL);
	group_bits1_set(port->OMODE, pin, 0UL);
	group_bits2_set(port->OSSEL, pin, spd);

	intx_enable();
}

void bsp_gpio_mode_out_od_spd(GPIO_T *port, uint8_t pin, uint32_t spd)
{
	intx_alloc();

	intx_disable();

	group_bits2_set(port->MODE, pin, 1UL);
	group_bits1_set(port->OMODE, pin, 1UL);
	group_bits2_set(port->OSSEL, pin, spd);

	intx_enable();
}

void bsp_gpio_mode_in_up(GPIO_T *port, uint8_t pin)
{
	intx_alloc();

	intx_disable();

	group_bits2_set(port->MODE, pin, 0UL);
	group_bits2_set(port->PUPD, pin, 1UL);

	intx_enable();
}

void bsp_gpio_mode_in_dn(GPIO_T *port, uint8_t pin)
{
	intx_alloc();

	intx_disable();

	group_bits2_set(port->MODE, pin, 0UL);
	group_bits2_set(port->PUPD, pin, 2UL);

	intx_enable();
}

void bsp_gpio_mode_in_ft(GPIO_T *port, uint8_t pin)
{
	intx_alloc();

	intx_disable();

	group_bits2_set(port->MODE, pin, 0UL);
	group_bits2_set(port->PUPD, pin, 0UL);

	intx_enable();
}

void bsp_gpio_mode_ain(GPIO_T *port, uint8_t pin)
{
	intx_alloc();

	intx_disable();

	group_bits2_set(port->MODE, pin, 3UL);
	group_bits2_set(port->PUPD, pin, 0UL);

	intx_enable();
}

void bsp_gpio_mode_set(GPIO_T *port, uint8_t pin, char pm)
{
	switch (pm)
	{
	case PIN_MODE_IN_UP:
	{
		bsp_gpio_mode_in_up(port, pin);
		break;
	}
	case PIN_MODE_IN_DN:
	{
		bsp_gpio_mode_in_dn(port, pin);
		break;
	}
	case PIN_MODE_IN_FLOAT:
	{
		bsp_gpio_mode_in_ft(port, pin);
		break;
	}
	case PIN_MODE_IN_AIN:
	{
		bsp_gpio_mode_ain(port, pin);
		break;
	};
	case PIN_MODE_OUT_SL_PP:
	{
		bsp_gpio_mode_out_pp_spd(port, pin, 0);
		break;
	}
	case PIN_MODE_OUT_SL_OD:
	{
		bsp_gpio_mode_out_od_spd(port, pin, 0);
		break;
	}
	case PIN_MODE_OUT_SM_PP:
	{
		bsp_gpio_mode_out_pp_spd(port, pin, 1);
		break;
	}
	case PIN_MODE_OUT_SM_OD:
	{
		bsp_gpio_mode_out_od_spd(port, pin, 1);
		break;
	}
	case PIN_MODE_OUT_SH_PP:
	{
		bsp_gpio_mode_out_pp_spd(port, pin, 3);
		break;
	}
	case PIN_MODE_OUT_SH_OD:
	{
		bsp_gpio_mode_out_od_spd(port, pin, 3);
		break;
	}
	default:
	{
		break;
	}
	}
}
